import { Injectable } from '@angular/core';
import { StorageService } from './storage.service';
import { environment } from '../../../environments/environment';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs';
//import { SignalR, IConnectionOptions, SignalRConnection, ConnectionTransports } from 'ng2-signalr';
declare const $: any;


enum ConnectionStatus {
    Reconnecting = 1,
    Connected = 2,
    Disconnected = 3
}
/**
 * WebSocket service
 * 
 * Author: Sorin Spiru
 * Date: 13.01.2018
 */
@Injectable()
export class SignalRService {
    private proxy: any;
    private connection: any;
    private subject: Subject<any>;
    private status: ConnectionStatus = ConnectionStatus.Reconnecting;
    private interval: any;

    public connect(hubName: string, service: string, callback: Function): Observable<any> {
        this.subject = new Subject<any>();
        this.connection = $.hubConnection(environment.serviceUrl + service, { qs: { access_token: this.getToken() } });
        this.proxy = this.connection.createHubProxy(hubName);

        this.proxy.on('sendTaskStatusesToUser', data => {
            this.subject.next(data);
        });

        this.connection.start().done(_ => {
            this.connected(callback);
        }).fail((error: any) => {
            console.log('Could not connect ' + error);
        });

        this.connection.error((error) => {
            console.log('Error ' + error);
        });

        this.connection.reconnecting(_ => {
            console.log('Reconnecting');
            this.status = ConnectionStatus.Reconnecting;
        });
        
        this.connection.reconnected(_ => {
            console.log('Reconnected');
            this.status = ConnectionStatus.Connected;
        });

        this.connection.disconnected(_ => {
            console.log('Disconnected');
            if(this.status == ConnectionStatus.Reconnecting) {                
                this.interval = setInterval(() => {
                    this.connection.start().done(_ => {
                        this.connected(callback);
                    });
                }, 5000);
                this.status = ConnectionStatus.Disconnected;
            }
        });

        return this.subject.asObservable();
    }

    private connected(callback: Function) {
        console.log('Connected');
        this.stopReconnecting();
        this.status = ConnectionStatus.Connected;
        callback();
    }

    public disconnect() {
        if (this.connection)
        {
            this.stopReconnecting();
            this.connection.stop();
        }
    }

    private stopReconnecting(){
        clearInterval(this.interval);
        this.interval = 0;
    }

    private getToken(): string {
        return StorageService.get().authData.access_token;
    }
}